
wbx.grid = (() => {
  // import
  let createDomByTagName, header, body, options, menu;

  const state = {
    selectedColumnIndex: 0,
    selectedRowIndex: 0
  };

  const dom = {
    wrapper: null
  };

  // events
  const onGridWrapperMouseUp = (e) => {
    console.log('wrapper on mouse up');
    console.log('this.resizeLocked: ', header.isResizeLocked());
    
    // render grid-body
    if (header.isResizeColumn()) {
      body.resizeColumns();
    }

    if (header.isResizeRow()) {
      body.resizeRows();
    }

    header.lockResize();
  }

  const onGridWrapperMouseMove = (e) => {
    if (!header.isResizeLocked()) {
      const startPos = header.getStartPosition();
      if (header.isResizeColumn()) {

        const startX = startPos.x;
        const width = startPos.width;

        const x = e.clientX;
        const xDiff = x - startX;

        let newWidth = width + xDiff;
        if (newWidth < 0) {
          newWidth = 0;
        }

        // console.log(xDiff);
        header.resizeColumnHeaderWidth(startPos.index, newWidth);

      } else if (header.isResizeRow()) {
        const startY = startPos.y;
        const height = startPos.height;
        
        const yDiff = e.clientY - startY;
        let newHeight = height + yDiff;
        if (newHeight < 0) {
          newHeight = 0;
        }

        header.resizeRowHeaderHeight(startPos.index, newHeight);
      }
    }
  }

  const addEventListeners = (container) => {
    container.onmousemove = onGridWrapperMouseMove.bind(this);
    container.onmouseup = onGridWrapperMouseUp.bind(this);
  };

  const render = (container) => {
    const gridWrapper = createDomByTagName('div');
    gridWrapper.classList.add('grid-wrapper');
    container.appendChild(gridWrapper);
    return gridWrapper;
  };

  const setConfig = () => {
    createDomByTagName = wbx.util.createDomByTagName;
    header = wbx.grid.header;
    body = wbx.grid.body;
    options = options;
    menu = wbx.grid.menu;
  }

  const init = (container, options) => {
    console.log('wbx.grid init');

    setConfig(options);

    dom.wrapper = render(container);

    wbx.grid.firstblock.init(dom.wrapper);
    wbx.grid.header.init(dom.wrapper);
    wbx.grid.body.init(dom.wrapper);
    wbx.grid.menu.init(dom.wrapper);

    addEventListeners(dom.wrapper);
  };

  const selectOneColumn = (index) => {
    unselect();

    // highlight header cell
    header.highlightColumnHeader(index);

    // highlight body cells
    body.highlightColumn(index);

    state.selectedColumnIndex = index;
  };

  const selectOneRow = (index) => {
    unselect();

    header.highlightRowHeader(index);
    body.highlightRow(index);

    state.selectedRowIndex = index;
  };

  const unselect = () => {
    menu.hide();

    body.unselectRow(state.selectedRowIndex);
    body.unselectColumn(state.selectedColumnIndex);
    body.unselectBodyCell();

    header.unselectRow(state.selectedRowIndex);
    header.unselectColumn(state.selectedColumnIndex);
    // unselectHeader();
  };

  const unselectHeader = () => {
    header.unselectRow(state.selectedRowIndex, state.selectedRowIndexEnd);
    header.unselectColumn(state.selectedColumnIndex, state.selectedColumnIndexEnd);
  };

  const deleteOneRow = (rowIndex) => {
    const cellsData = wbx.model.getCellsData();
    cellsData.splice(rowIndex, 1);
    wbx.model.row.count--;
    wbx.model.row.heights.splice(rowIndex, 1);

    header.remove();
    body.remove();

    header.reRender(dom.wrapper);
    body.reRender(dom.wrapper);
  };

  const insertOneRow = (rowIndex) => {
    // const index = rowIndex ? rowIndex : state.selectedRowIndex;
    const cellsData = wbx.model.getCellsData();
    cellsData.splice(rowIndex, 0, Array(wbx.model.column.count).fill(''));
    wbx.model.row.count++;
    wbx.model.row.heights.splice(rowIndex, 0, '20px');

    header.remove();
    body.remove();

    header.reRender(dom.wrapper);
    body.reRender(dom.wrapper);
  };

  const deleteOneColumn = (columnIndex) => {
    const cellsData = wbx.model.getCellsData();
    cellsData.map(oneRow => oneRow.splice(columnIndex, 1));
    wbx.model.column.count--;
    wbx.model.column.widths.splice(columnIndex, 1);
    
    header.remove();
    body.remove();

    header.reRender(dom.wrapper);
    body.reRender(dom.wrapper);
  };

  const insertOneColumn = (columnIndex) => {
    const cellsData = wbx.model.getCellsData();
    // cellsData.splice(rowIndex, 0, Array(wbx.model.column.count).fill(''));

    cellsData.map(oneRow => oneRow.splice(columnIndex, 0, ''));
    wbx.model.column.count++;
    wbx.model.column.widths.splice(columnIndex, 0, '80px');

    header.remove();
    body.remove();

    header.reRender(dom.wrapper);
    body.reRender(dom.wrapper);
  };

  const getSelectedRowIndex = () => state.selectedRowIndex;
  const getSelectedColumnIndex = () => state.selectedColumnIndex;

  const setSelectedIndex = (rowIndex, columnIndex, rowIndexEnd, columnIndexEnd) => {
    state.selectedRowIndex = rowIndex;
    state.selectedColumnIndex = columnIndex;
    state.selectedRowIndexEnd = rowIndexEnd;
    state.selectedColumnIndexEnd = columnIndexEnd;
  };

  return {
    dom: dom,
    init: init,
    selectOneColumn: selectOneColumn,
    selectOneRow: selectOneRow,
    deleteOneRow: deleteOneRow,
    insertOneRow: insertOneRow,
    deleteOneColumn: deleteOneColumn,
    insertOneColumn: insertOneColumn,
    getSelectedRowIndex: getSelectedRowIndex,
    getSelectedColumnIndex: getSelectedColumnIndex,
    unselect: unselect,
    unselectHeader: unselectHeader,
    setSelectedIndex: setSelectedIndex
  };

})();